require 'optparse'

module AsciidocBib

  # Class to read in asciidoc-bib options from command-line, and 
  # store results in an accessible form.
  #
  class Options
    # Location of bib file to read references from.
    attr_reader :bibfile
    # Location of file to process.
    attr_reader :filename
    # Flag to indicate if links should be included.
    attr_reader :links
    # Name of style to use for displaying citations and references.
    attr_reader :style

    # Sets up options for the program, including:
    # * location of bib file
    # * whether internal links should be added
    # * sorting of references
    # * style of references
    # * name of file to process
    #
    def initialize(program_name = 'asciidoc-bib')
      @bibfile = ''
      @links = true
      @numeric_order = :alphabetical
      @style = AsciidocBib::Styles.default_style

      options = OptionParser.new do |opts|
        opts.banner = "Usage: #{program_name} filename"
        opts.on("-h", "--help", "help message") do |v|
          puts "#{program_name} #{AsciidocBib::VERSION}"
          puts
          puts options
          puts
          puts "All styles available through CSL are supported."
          puts "The default style is 'apa'."
          exit!
        end
        opts.on("-b", "--bibfile FILE", "location of bib file") do |v|
          @bibfile = v
        end
        opts.on("-n", "--no-links", "do not add internal links") do |v|
          @links = false
        end
        opts.on('', '--numeric-alphabetic-order', 'sort numeric styles in alphabetical order (DEFAULT)') do |v|
          @numeric_order = :alphabetical
        end
        opts.on('', '--numeric-appearance-order', 'sort numeric styles in order of appearance') do |v|
          @numeric_order = :appearance
        end
        opts.on("-s", "--style STYLE", "reference style") do |v|
          @style = v
        end
        opts.on("-v", "--version", "show version") do |v|
          puts "#{program_name} version #{AsciidocBib::VERSION}"
          exit!
        end
      end

      begin
        options.parse!
      rescue 
        puts options
        exit!
      end

      # unless specified by caller, try to find the bibliography
      if @bibfile.empty?
        @bibfile = AsciidocBib::FileHandlers.find_bibliography "."
        if @bibfile.empty?
          @bibfile = AsciidocBib::FileHandlers.find_bibliography "#{ENV['HOME']}/Documents"
        end
      end
      if @bibfile.empty?
        puts "Error: could not find a bibliography file"
        exit
      end
      unless AsciidocBib::Styles.valid? @style
        puts "Error: style #{@style} was not one of the available styles"
        exit
      end

      if ARGV.length == 1
        @filename = ARGV[0]
      else
        puts "Error: a single file to convert must be given"
        exit
      end

      puts "Reading biblio: #{@bibfile}"
      puts "Reference style: #{@style}"
    end

    # Convenience method to check @numeric_order.
    # This is used in place of making the @numeric_order field visible
    # to external classes.
    def numeric_in_appearance_order?
      @numeric_order == :appearance
    end
  end
end

